package com.tengju.bff.interfaces.covercharge.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.idanchuang.component.config.apollo.util.ConfigUtil;
import com.idanchuang.component.redis.util.RedisUtil;
import com.tengju.bff.interfaces.covercharge.constant.HeavyKeyEnum;
import com.tengju.bff.interfaces.covercharge.constant.MessageTemplateIdEnum;
import com.tengju.bff.interfaces.covercharge.constant.SignIdentityEnum;
import com.tengju.bff.interfaces.covercharge.entity.vo.PersonalGiveQuery;
import com.tengju.bff.interfaces.covercharge.entity.vo.PersonalGiveVo;
import com.tengju.bff.interfaces.covercharge.entity.vo.PlayWithConfirmationPreviewVo;
import com.tengju.bff.interfaces.covercharge.entity.vo.PlayWithConfirmationVo;
import com.tengju.bff.interfaces.covercharge.service.IServiceLetaxWithdrawLogService;
import com.tengju.bff.interfaces.covercharge.service.IServiceSelfCertificationWithdrawService;
import com.tengju.bff.interfaces.covercharge.service.ISmsConfirmationService;
import com.tengju.bff.interfaces.covercharge.service.message.client.UserMessageClient;
import com.tengju.bff.interfaces.covercharge.util.DateTimeUtils;
import com.tengju.bff.interfaces.covercharge.util.redis.HeavyUtil;
import com.tengju.user.application.sms.SmsBizService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 确认验证
 *
 * @author qmm
 */
@Service
@Slf4j
public class SmsConfirmationServiceImpl implements ISmsConfirmationService {
    @Autowired
    private IServiceSelfCertificationWithdrawService serviceSelfCertificationWithdrawService;

    //每页数量
    private final static Integer PAGE_SIZE = 10000;

    @Value("${system.env}")
    String env;

    @Autowired
    private IServiceLetaxWithdrawLogService serviceLetaxWithdrawLogService;

    @Autowired
    private UserMessageClient userMessageClient;

    @Autowired
    private SmsBizService smsBizService;

    @Override
    public String send(String type, String approvers, String phone, String approversName) {
        String sendKey = type + HeavyKeyEnum.PAID_CONFIRM_SMS.getCode() + approvers;
        if(HeavyUtil.isRun(sendKey, 60000)) {
            return "您已获取过验证码,请一分钟后再发送";
        }
        //四位数字验证码
        String valCode = String.valueOf((int)((Math.random()*9+1)*1000));
        String valInsertKey = type + HeavyKeyEnum.PAID_CONFIRM_SMS_VALUE.getCode() + approvers;
        RedisUtil.getInstance().set(valInsertKey, valCode);
        RedisUtil.getInstance().expire(valInsertKey, 600000);
        String content = String.format("有人正在进行批量打款:%s;验证码为:%s", approversName, valCode);
        String url = ConfigUtil.getConfig().getString("is_withdrawal_send_message", "");
        if(!"".equals(url)) {

            smsBizService.sendChargeBatchPayment(phone,approversName,valCode);
            //userMessageClient.sendMobileMessageByTemplateWithMobile(phone, MessageTemplateIdEnum.ABM.getCode(), content);

        }

        return "";
    }

    @Override
    public String validation(String type, String approvers, String code) {


        if (env.equals("dev") || env.equals("test") || env.equals("pre")) {
            if("0000".equals(code)){
                return "";
            }
        }

        //四位数字验证码
        String valCode = "";
        String valInsertKey = type + HeavyKeyEnum.PAID_CONFIRM_SMS_VALUE.getCode() + approvers;
        valCode = RedisUtil.getInstance().get(valInsertKey);
        if(valCode == null) {
            return "你还没有发送验证码";
        }
        if(!valCode.equals(code)) {
            return "验证码不正确";
        }

        return "";
    }

    @Override
    public Boolean validationDone(String type, String approvers, String code) {
        String valInsertKey = type + HeavyKeyEnum.PAID_CONFIRM_SMS_VALUE.getCode() + approvers;

        return RedisUtil.getInstance().del(valInsertKey);
    }

    @Override
    public PlayWithConfirmationPreviewVo playWithConfirmationWithBatchNotSinceCertification(PlayWithConfirmationVo req) {
        //判断是否传入周期时间(此条件为必要条件)
        String date = req.getDate();
        //获取周期开始和结束时间
        String cycleDay = ConfigUtil.getConfig().getString("withdraw.cycle.day", "10");
        String startDateStr = DateTimeUtils.parseDateAsString(
                DateTimeUtils.addMonths(DateUtil.parse(date, DateTimeUtils.MONTH_FORMAT), -1),
                DateTimeUtils.MONTH_FORMAT)
                + "-" + (Integer.parseInt(cycleDay) + 1) + " 00:00:00";

        String endDateStr = DateTimeUtils.parseDateAsString(
                DateUtil.parse(date, DateTimeUtils.MONTH_FORMAT),
                DateTimeUtils.MONTH_FORMAT)
                + "-" + cycleDay + " 23:59:59";
        //参数拼接
        PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
        personalGiveQuery.setAuthType(SignIdentityEnum.regist_soho.getCode());
        personalGiveQuery.setCycleDate(req.getDate());
        personalGiveQuery.setStartDate(startDateStr);
        personalGiveQuery.setEndDate(endDateStr);
        personalGiveQuery.setCycleAddIdList(req.getCycleAddIds());
        //查询符合条件的周期记录总数
        Page<PersonalGiveVo> pageResultTotal = serviceLetaxWithdrawLogService.queryPersonalGiveAllListWithIds(new Page<>(1, 1), personalGiveQuery);
        //获取总数
        long count = pageResultTotal.getTotal();
        //获取页数
        int page = Math.toIntExact((count / PAGE_SIZE + (count % PAGE_SIZE > 0 ? 1 : 0)));
        BigDecimal amount = BigDecimal.ZERO;
        Integer size = 0;
        //分页获取符合条件页数
        for (int i = 1; i <= page; i++) {
            Page<PersonalGiveVo> pageResult = serviceLetaxWithdrawLogService.queryPersonalGiveAllListWithIds(new Page<>(i, PAGE_SIZE), personalGiveQuery);
            List<PersonalGiveVo> list = pageResult.getRecords();
            if (!CollectionUtils.isEmpty(list)) {
                for(PersonalGiveVo personalGiveVo : list) {
                    personalGiveVo.setFee(personalGiveVo.getPassMoney().multiply(personalGiveVo.getRatio()));
                    amount = amount.add(personalGiveVo.getPassMoney().subtract(personalGiveVo.getFee()));
                }
                size += list.size();
            }
        }
        PlayWithConfirmationPreviewVo playWithConfirmationPreviewVo = new PlayWithConfirmationPreviewVo();

        playWithConfirmationPreviewVo.setSelectNumberOf(String.valueOf(size));
        playWithConfirmationPreviewVo.setAggregateAmount(String.valueOf(amount));

        return playWithConfirmationPreviewVo;
    }

    @Override
    public PlayWithConfirmationPreviewVo playWithConfirmationWithAllNotSinceCertificationPage(PlayWithConfirmationVo req) {
        //判断是否传入周期时间(此条件为必要条件)
        String date = req.getDate();
        //获取周期开始和结束时间
        String cycleDay = ConfigUtil.getConfig().getString("withdraw.cycle.day", "10");
        String startDateStr = DateTimeUtils.parseDateAsString(
                DateTimeUtils.addMonths(DateUtil.parse(date, DateTimeUtils.MONTH_FORMAT), -1),
                DateTimeUtils.MONTH_FORMAT)
                + "-" + (Integer.parseInt(cycleDay) + 1) + " 00:00:00";

        String endDateStr = DateTimeUtils.parseDateAsString(
                DateUtil.parse(date, DateTimeUtils.MONTH_FORMAT),
                DateTimeUtils.MONTH_FORMAT)
                + "-" + cycleDay + " 23:59:59";
        //参数拼接
        PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
        personalGiveQuery.setAuthType(SignIdentityEnum.regist_soho.getCode());
        personalGiveQuery.setCycleDate(req.getDate());
        personalGiveQuery.setStartDate(startDateStr);
        personalGiveQuery.setEndDate(endDateStr);
        //查询符合条件的周期记录总数
        Page<PersonalGiveVo> pageResultTotal = serviceLetaxWithdrawLogService.queryPersonalGiveAllListAllPaid(new Page<>(1, 1), personalGiveQuery);
        //获取总数
        long count = pageResultTotal.getTotal();
        //获取页数
        int page = Math.toIntExact((count / PAGE_SIZE + (count % PAGE_SIZE > 0 ? 1 : 0)));
        BigDecimal amount = BigDecimal.ZERO;
        Integer size = 0;
        //分页获取符合条件页数
        for (int i = 1; i <= page; i++) {
            Page<PersonalGiveVo> pageResult = serviceLetaxWithdrawLogService.queryPersonalGiveAllListAllPaid(new Page<>(i, PAGE_SIZE), personalGiveQuery);
            List<PersonalGiveVo> list = pageResult.getRecords();
            if (!CollectionUtils.isEmpty(list)) {
                for(PersonalGiveVo personalGiveVo : list) {
                    personalGiveVo.setFee(personalGiveVo.getPassMoney().multiply(personalGiveVo.getRatio()));
                    amount = amount.add(personalGiveVo.getPassMoney().subtract(personalGiveVo.getFee()));
                }
                size += list.size();
            }
        }
        PlayWithConfirmationPreviewVo playWithConfirmationPreviewVo = new PlayWithConfirmationPreviewVo();

        playWithConfirmationPreviewVo.setSelectNumberOf(String.valueOf(size));
        playWithConfirmationPreviewVo.setAggregateAmount(String.valueOf(amount));

        return playWithConfirmationPreviewVo;
    }

    /**
     * 自认证批量打款确认信息
     * @param req
     * @return
     */
    @Override
    public PlayWithConfirmationPreviewVo playWithConfirmationWithBatchSinceCertification(PlayWithConfirmationVo req) {
        List<Integer> cycleAddIdList = req.getCycleAddIds();
        PlayWithConfirmationPreviewVo playWithConfirmationPreviewVo = serviceSelfCertificationWithdrawService.getTotalAmountWithList(cycleAddIdList);

        return playWithConfirmationPreviewVo;
    }

    /**
     * 自认证全量打款确认信息
     * @param req
     * @return
     */
    @Override
    public PlayWithConfirmationPreviewVo playWithConfirmationWithAllSinceCertification(PlayWithConfirmationVo req) {
        PlayWithConfirmationPreviewVo playWithConfirmationPreviewVo = new PlayWithConfirmationPreviewVo();
        playWithConfirmationPreviewVo = serviceSelfCertificationWithdrawService.getTotalAmountWithAll();

        return playWithConfirmationPreviewVo;
    }
}
